package downloader;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.CyclicBarrier;

public class DownloaderThread extends Thread {
    private URL url;
    private File file;
    private Part part;
    private CyclicBarrier barrier;

    public DownloaderThread(Part part,File file,String url, CyclicBarrier barrier) {
        this.part = part;
        this.url = generateURL(url);
        this.file = file;
        this.barrier = barrier;
    }

    private URL generateURL(String url) {
        URL ret = null;
        try {
            ret = new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        return ret;
    }

    private void closeStream(InputStream inputStream,
                             HttpURLConnection urlConnection,
                             RandomAccessFile randomAccessFile)
            throws IOException {
        inputStream.close();
        urlConnection.disconnect();
        randomAccessFile.close();
    }

    @Override
    public void run() {
        try {
            int begin = part.getBegin();
            int end = begin + part.getLength();

            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setRequestProperty("Range", "bytes=" + begin + "-" + end);
            if (urlConnection.getResponseCode() == 206) {
                RandomAccessFile raf = new RandomAccessFile(file, "rw");
                raf.seek(begin);
                InputStream inputStream = urlConnection.getInputStream();
                byte[] buffer = new byte[1024];
                int perRead;
                while (-1 != (perRead = inputStream.read(buffer))) {
                    raf.write(buffer, 0, perRead);
                    part.setCurrentLength(part.getCurrentLength() + perRead);
                }
                closeStream(inputStream, urlConnection, raf);
            }
            barrier.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
